#ifndef _BITSTREA_H
#define _BITSTREA_H

#include "typedfs.h"


/** for reading and writting from/to bitstream */
typedef struct {
   long Total;
   FILE *HostFile;
   uint8_t *RealBufStart;
   unsigned BufSize;

   uint32_t buf;		/* bit buffer */
   int pb;			/* already readed bits from buf */
   uint16_t *pd;		/* first not readed or not written input data*/
   uint16_t *pe;		/* after end of data */
 } bits_t;


#ifdef __cplusplus
extern "C" {
#endif

extern const uint16_t Hu2Sizes[8];
extern const uint8_t Hu2Prefix[8];

void sq_rdinit(bits_t *pbits,void *BufStart,unsigned BufSize,unsigned long TotalLin,FILE *f);
uint16_t sq_rdn(bits_t *pbits, int n);
void sq_rdUnl(bits_t *pbits,uint8_t *array, int n);

void sq_wrinit(bits_t *pbits,void *BufStart,unsigned BufSize,unsigned long TotalLin,FILE *f);
void sq_wrn(bits_t *pbits, unsigned u, int n);
void sq_wrUnl(bits_t *pbits, uint8_t *array, int n);

void FillBuffer(bits_t *pbits);
void TotalFlush(bits_t *pbits);

#define sq_wrh(pbits,phuf,ch) \
 sq_wrn(pbits,phuf->cod[ch],phuf->ln[ch])

#ifdef __cplusplus
}
#endif



/* huffman decoding */

typedef long int count_t;

#define MAX_SPDA_BITS	10
#define MAX_SPDA_LEN	(1<<MAX_SPDA_BITS)
#define MAX_BITS	16
#define MAX_CODES	1025   /* Pi 0x200 */
#define OUT_OVER	1025   /* Pi 0x100 */

typedef uint8_t* hash_t;
typedef struct {
  count_t cn;
  unsigned ch;
} ch_tab_t;

typedef struct {
  int8_t ln;			/* character code */
  uint8_t  ch;	/* F WORD */	/* character lens .. if >=0x80 token */
} huf_chln_t;

typedef struct {
  huf_chln_t chln[MAX_SPDA_LEN];/* character codes decode array */
  huf_chln_t chln1[MAX_CODES];	/* for codes with more than bn bits */
  int  bn;			/* ch,ln arrays convert max bn bits codes */
  unsigned cd_ln[MAX_BITS+1];	/* distribution of bits */
  unsigned cd_ch[MAX_BITS+1];	/* distribution of codes codes */
 }huf_rd_t;

typedef struct 
{
  uint16_t  cod[MAX_CODES];	/* characters codes */
  uint8_t  ln[MAX_CODES];	/* characters lens */
} huf_wr_t;


#ifdef __cplusplus
extern "C" {
#endif

int sq_huffman(count_t* ch_cn, uint8_t* ch_blen, unsigned* ch_blcn, int cod_num, ch_tab_t *ch_tab);
unsigned sq_rdh1(bits_t *pbits,const huf_rd_t *phuf);
int sq_rdhufi(huf_rd_t *phuf,int m,int bn,uint8_t *ca);
int sq_wrhufi(huf_wr_t *phuf, unsigned* ch_blencn,int cod_num);


#ifdef __cplusplus
}
#endif


#endif